package com.nuoniu.sibanyun.service.crm.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nuoniu.sibanyun.common.exception.NuoNiuException;
import com.nuoniu.sibanyun.common.stream.Iterables;
import com.nuoniu.sibanyun.common.text.PinyinUtils;
import com.nuoniu.sibanyun.entity.crm.CrmDefineField;
import com.nuoniu.sibanyun.entity.crm.CrmSysField;
import com.nuoniu.sibanyun.entity.dto.CrmDefineFieldDto;
import com.nuoniu.sibanyun.mapper.crm.CrmDefineFieldMapper;
import com.nuoniu.sibanyun.service.crm.ICrmDefineFieldService;
import com.nuoniu.sibanyun.service.crm.ICrmSysFieldService;
import com.nuoniu.sibanyun.service.crm.ICrmUserFieldService;
import com.nuoniu.sibanyun.userThread.UserInfo;
import com.nuoniu.sibanyun.userThread.UserThreadLocal;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 客户管理自定义字段 服务实现类
 * </p>
 *
 * @author baiqiang
 * @since 2020-06-15
 */
@Service
@Log4j2
public class CrmDefineFieldServiceImpl extends ServiceImpl<CrmDefineFieldMapper, CrmDefineField> implements ICrmDefineFieldService {

    @Autowired
    private CrmDefineFieldMapper fieldMapper;
    @Autowired
    private ICrmUserFieldService crmUserFieldService;

    @Override
    public List<CrmDefineField> getDefineFieldList(String source) {
        UserInfo userInfo = UserThreadLocal.get();
        CrmDefineField crmDefineField = new CrmDefineField();
        QueryWrapper<CrmDefineField> queryWrapper = new QueryWrapper<>(crmDefineField);
        if (StringUtils.isBlank(source)) {
           throw new NuoNiuException("参数错误");
        }
        queryWrapper.eq("source", source);
        queryWrapper.eq("company_id", userInfo.getCompanyId());
        queryWrapper.orderByAsc("sort");
        return list(queryWrapper);
    }



    @Override
    public void saveFieldVal(CrmDefineFieldDto crmDefineFieldDto) {
        UserInfo userInfo = UserThreadLocal.get();
        CrmDefineField crmDefineField = new CrmDefineField();
        crmDefineField.setUpdateUserId(userInfo.getUserId());
        crmDefineField.setUpdateUserName(userInfo.getRealName());
        crmDefineField.setVal(crmDefineFieldDto.getVal());
        QueryWrapper<CrmDefineField> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",crmDefineFieldDto.getId());
        queryWrapper.eq("company_id",userInfo.getCompanyId());
        update(crmDefineField,queryWrapper);
    }

    @Override
    public void saveField(CrmDefineFieldDto crmDefineFieldDto) {
        LocalDateTime now = LocalDateTime.now();
        UserInfo userInfo = UserThreadLocal.get();
        if(null == userInfo.getCompanyId() || null == userInfo.getUserId()){
            throw new NuoNiuException("参数错误");
        }
        CrmDefineField crmDefineField = new CrmDefineField();
        BeanUtils.copyProperties(crmDefineFieldDto,crmDefineField);
        Integer dataType = crmDefineField.getDataType();
        String source = crmDefineField.getSource();
        if(null == crmDefineField.getId()){
            crmDefineField.setCompanyId(userInfo.getCompanyId());
            crmDefineField.setCompanyName(userInfo.getCompanyName());
            crmDefineField.setCreateUserId(userInfo.getUserId());
            crmDefineField.setCreateUserName(userInfo.getRealName());
            crmDefineField.setCreateDate(now);
            crmDefineField.setIsSearch(true);
            crmDefineField.setOnOff(true);
            crmDefineField.setStatus(0);
            crmDefineField.setOnLocked(false);

            Integer lastSort = getLastSort(crmDefineFieldDto.getSource());
            if(null == lastSort)lastSort = 0;
            crmDefineField.setSort(lastSort + 1);

            String code = PinyinUtils.getFirstSpell(crmDefineField.getName());
            crmDefineField.setCode(code + crmDefineField.getSort());
            if(1 == dataType || 2 == dataType){
                crmDefineField.setSysName(crmDefineField.getName());
            }else{
                crmDefineField.setOnFill(false);
            }

            this.updateUserFiled(crmDefineField);
        }
        crmDefineField.setUpdateUserId(userInfo.getUserId());
        crmDefineField.setUpdateUserName(userInfo.getRealName());
        crmDefineField.setUpdateDate(now);
        saveOrUpdate(crmDefineField);
    }

    @Override
    public Integer getLastSort(String source) {
        UserInfo userInfo = UserThreadLocal.get();
        Integer lastSort = baseMapper.getLastSort(userInfo.getCompanyId(), source);
        return lastSort;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void batchSaveField(List<CrmDefineFieldDto> crmDefineFieldDtos) {
        //
        Map<Long,CrmDefineField> onSysFills = new HashMap<>();
        LocalDateTime now = LocalDateTime.now();
        UserInfo userInfo = UserThreadLocal.get();
        //系统管理员 权限
        if(1 == userInfo.getUserId()){
            Map<Long,CrmDefineField> onSysFills2 = mapSysOnfill("");
            onSysFills.putAll(onSysFills2);
        }
        Integer lastSort = null;
        if(crmDefineFieldDtos.size() > 0 ){
            lastSort = baseMapper.getLastSort(userInfo.getCompanyId(), crmDefineFieldDtos.get(0).getSource());
            if(null == lastSort)lastSort = 0;
        }
        Integer sort = lastSort;
        List<CrmDefineField> crmDefineFieldList = new ArrayList<>();
        //java8 Iterable自定义工具
        Iterables.forEach(crmDefineFieldDtos, (index, crmDefineFieldDto) -> {
            CrmDefineField crmDefineField = new CrmDefineField();
            BeanUtils.copyProperties(crmDefineFieldDto,crmDefineField);
            Integer dataType = crmDefineField.getDataType();
            if(null == crmDefineField.getId()){
                crmDefineField.setCompanyId(userInfo.getCompanyId());
                crmDefineField.setCompanyName(userInfo.getCompanyName());
                crmDefineField.setCreateUserId(userInfo.getUserId());
                crmDefineField.setCreateUserName(userInfo.getRealName());
                crmDefineField.setCreateDate(now);
                crmDefineField.setIsSearch(true);
                crmDefineField.setOnOff(true);
                crmDefineField.setStatus(0);
                crmDefineField.setOnLocked(false);
                crmDefineField.setSort(sort + index + 1);
                String code = PinyinUtils.getFirstSpell(crmDefineField.getName());
                crmDefineField.setCode(code + crmDefineField.getSort());
                if(1 == dataType || 2 == dataType){
                    crmDefineField.setSysName(crmDefineField.getName());
                }else{
                    //如果是新增 继承字段
                    //1.查询 是否已经存在
                    int countParentIdFiled = this.countParentIdFiled(crmDefineField.getParentId(), crmDefineField.getSource());
                    if(countParentIdFiled > 0){
                        throw new NuoNiuException("-->>" +crmDefineField.getParentName() + "<--，该字段已经被继承，请重新选择");
                    }
                    crmDefineField.setOnFill(false);
                }
                this.updateUserFiled(crmDefineField);
            }else{
                if(crmDefineField.getDataType() == 2){
                    /***查询 详情*/
                    CrmDefineField defineField = getById(crmDefineField.getId());
                    //修改了 自定义字段 类型
                    if(!defineField.getType().equals(crmDefineField.getType())){
                        /**是否 已使用*/
                        String source = defineField.getSource();
                        String tableName = "";
                        switch (source){
                            case "crm":tableName = "pub_customer";break;
                            case "linkMan":tableName = "crm_linkman";break;
                            case "touch":tableName = "crm_touch";break;
                            case "activity":tableName = "crm_activity";break;
                            case "business":tableName = "crm_business";break;
                        }
                        int number = baseMapper.countDefineFieldUsedNumber(tableName,userInfo.getCompanyId(), crmDefineField.getId().intValue());
                        if(number > 0){
                            throw new NuoNiuException("编辑失败,-->>"+ crmDefineField.getName() +"<--自定义字段已经被使用,使用记录数:" + number + ",请先清除使用记录再进行编辑；放弃当前修改请'刷新'");
                        }
                        //查询是否有继承关系,并修改继承关系
                        QueryWrapper<CrmDefineField> queryWrapper = new QueryWrapper<>();
                        queryWrapper.eq("parent_id",crmDefineField.getId());
                        /***查询 子集*/
                        List<CrmDefineField> list = list(queryWrapper);
                        List<CrmDefineField> collect = list.stream().map(f -> {
                            CrmDefineField newCdf = new CrmDefineField();
                            newCdf.setId(f.getId());
                            newCdf.setType(crmDefineField.getType());
                            newCdf.setVal(crmDefineField.getVal());
                            return newCdf;
                        }).collect(Collectors.toList());
                        if(collect.size() > 0){
                            /***更新 子集*/
                            saveOrUpdateBatch(collect);
                        }
                    }

                }

            }
            crmDefineField.setUpdateUserId(userInfo.getUserId());
            crmDefineField.setUpdateUserName(userInfo.getRealName());
            crmDefineField.setUpdateDate(now);
            crmDefineFieldList.add(crmDefineField);

        });
        if(crmDefineFieldList.size() > 0){
            /***更新 自定义*/
            saveOrUpdateBatch(crmDefineFieldList);
            System.out.println("ok");
        }
    }

    @Override
    public void deleteOne(Integer id) {
        UserInfo userInfo = UserThreadLocal.get();
        CrmDefineField crmDefineField = getById(id);
        String source = crmDefineField.getSource();
        String tableName = "";
        switch (source){
            case "crm":tableName = "pub_customer";break;
            case "company":tableName = "pub_customer";break;
            case "vendor":tableName = "pub_customer";break;
            case "linkMan":tableName = "crm_linkman";break;
            case "touch":tableName = "crm_touch";break;
            case "activity":tableName = "crm_activity";break;
            case "business":tableName = "crm_business";break;
            case "finance":tableName = "crm_finance_info";break;
        }
        if( null == crmDefineField){
            throw new NuoNiuException("删除失败,参数无效");
        }
        if(!crmDefineField.getCompanyId().equals(userInfo.getCompanyId()) ){
            throw new NuoNiuException("删除失败,越权操作");
        }
        Integer dataType = crmDefineField.getDataType();
        if (dataType == 1){
           throw new NuoNiuException("删除失败,系统字段不可删除");
        }
        if(dataType == 2){
            //1.是否被继承
            QueryWrapper<CrmDefineField> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("parent_id",id);
            int count = count(queryWrapper);
            if(count > 0){
                throw new NuoNiuException("删除失败,该自定义字段已经被继承,请先解绑继承关系再进行删除");
            }
            //2.是否 已使用

            int number = baseMapper.countDefineFieldUsedNumber(tableName,userInfo.getCompanyId(), id);
            if(number > 0){
                throw new NuoNiuException("删除失败,该字段已经使用,不能删除");
            }
        }
        boolean b = removeById(id);
        if(!b){
            throw new NuoNiuException("删除失败");
        }
    }

    @Override
    public HashMap<Long,CrmDefineField> mapSysOnfill(String source) {
        HashMap<Long,CrmDefineField> map = new HashMap<>();
        UserInfo userInfo = UserThreadLocal.get();
        CrmDefineField field = new CrmDefineField();
        field.setCompanyId(userInfo.getCompanyId());
        field.setSource(source);
        field.setDataType(1);
        List<CrmDefineField> list = baseMapper.findList(field);
        list.forEach(f->{
            map.put(f.getId(),f);
        });
        return map;
    }

    @Override
    public List<CrmDefineField> getCrmDefineFieldList(String source) {
        UserInfo userInfo = UserThreadLocal.get();
        return fieldMapper.getCrmDefineFieldList(source, userInfo.getCompanyId());
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean changeOnLocked(CrmDefineFieldDto crmDefineFieldDto) {
        if(null == crmDefineFieldDto.getOnLocked()  || null == crmDefineFieldDto.getId()){
            return false;
        }
        CrmDefineField crmDefineField = new CrmDefineField();
        BeanUtils.copyProperties(crmDefineFieldDto,crmDefineField);
        if(crmDefineField.getOnLocked()){
            crmDefineField.setOnOff(true);
            crmDefineField.setOnAppOff(true);
        }
        boolean b = updateById(crmDefineField);
        if(b){
            CrmDefineField newCrmDefineField1 = getById(crmDefineField.getId());
            updateOnLockedFromSystem(newCrmDefineField1);
        }
        return true;
    }

    @Override
    public boolean updateOnLockedFromSystem(CrmDefineField crmDefineField) {
        UserInfo userInfo = UserThreadLocal.get();
        boolean isOk = false;
        Integer userId = userInfo.getUserId();
        //系统管理员 权限
        if(1 == userId && 1 == userInfo.getCompanyId() ){
            isOk = baseMapper.updateOnLockedFromSystem(crmDefineField);
        }
        return isOk;
    }

    @Override
    public void updateUserFiled(CrmDefineField crmDefineField) {
        UserInfo userInfo = UserThreadLocal.get();
        Integer dataType = crmDefineField.getDataType();
        String source = crmDefineField.getSource();
        //获取code 用于更新 个性化 自定义列
        String finalCode = crmDefineField.getCode();
        if(3 == dataType || 4 == dataType){
            finalCode = crmDefineField.getParentCode();
        }
        String type = "";
        switch (source){
            case "crm": type = "0,1,2";break;
            case "linkMan":type="3";break;
            case "touch":type="4";break;
        }
        //1.更新 该公司 自定义列设置
        if(StringUtils.isNotBlank(type)){
            crmUserFieldService.concatUserField(userInfo.getCompanyId(),type,finalCode);
        }
    }

    @Override
    public int countParentIdFiled(Integer parentId, String source) {
        QueryWrapper<CrmDefineField> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id",parentId);
        queryWrapper.eq("source",source);
        int count = count(queryWrapper);
        return count;
    }

    @Override
    public CrmDefineField crmDefineFieldByCode(String source,String code) {
        UserInfo userInfo = UserThreadLocal.get();
        if(StringUtils.isBlank(source) ||StringUtils.isBlank(code) || null == userInfo.getCompanyId()){
            return null;
        }
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("source",source);
        queryWrapper.eq("code",code);
        queryWrapper.eq("company_id",userInfo.getCompanyId());
        queryWrapper.last("LIMIT 1");
        CrmDefineField one = getOne(queryWrapper,false);
        return one;
    }







    /*******************************    APP    *************************************/


    @Override
    public List<CrmDefineField> getDefineFieldListApp(String source) {
        UserInfo userInfo = UserThreadLocal.get();
        QueryWrapper<CrmDefineField> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isBlank(source)) {
            throw new NuoNiuException("参数错误");
        }
        queryWrapper.eq("source", source);
        queryWrapper.eq("on_app_off",1);
        queryWrapper.eq("company_id", userInfo.getCompanyId());
        queryWrapper.orderByAsc("sort");
        return list(queryWrapper);
    }



}
